package config

import (
	"errors"
	"gdei_healthy_colly/log"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"strings"
)

type AccountConfig struct {
	ID       string
	Username string
	Password string
	Remember bool
}

type ServerChanConfig struct {
	Key  []string
	Addr string
}

type Config struct {
	Accounts   []AccountConfig
	ServerChan *ServerChanConfig
	Retry      int
	RetryDelay int
	CommitTime string
}

var Cfg = new(Config)

type AcOption func(ac AccountConfig)

func WithUsername(username string) AcOption {
	return func(ac AccountConfig) {
		username = strings.TrimSpace(username)
		if username == "" || ac.Username == username {
			return
		}
		ac.Username = username
	}
}

func WithPassword(password string) AcOption {
	return func(ac AccountConfig) {
		password = strings.TrimSpace(password)
		if password == "" || ac.Password == password {
			return
		}
		ac.Password = password
	}
}

// 添加用户
func (c *Config) AddAccount(id string, options ...AcOption) (err error) {
	// 如果用户已经存在，则进行修改操作
	for _, v := range c.Accounts {
		if v.ID == id {
			return c.EditAccount(id, options...)
		}
	}
	ac := AccountConfig{
		ID:       id,
		Remember: true,
	}
	if len(options) > 0 {
		for _, fn := range options {
			fn(ac)
		}
	}
	return viper.WriteConfig()
}

// 删除账号
func (c *Config) DeleteAccount(id string, _ ...AcOption) (err error) {
	for k, v := range c.Accounts {
		if v.ID == id {
			c.Accounts = append(c.Accounts[:k], c.Accounts[k+1:]...)
			return viper.WriteConfig()
		}
	}
	return errors.New("账号不存在")
}

// 修改账户
func (c *Config) EditAccount(id string, options ...AcOption) (err error) {
	var index = -1
	for k, v := range c.Accounts {
		if v.ID == id {
			index = k
			break
		}
	}
	if index == -1 {
		return errors.New("账号不存在")
	}
	ac := AccountConfig{
		ID:       id,
		Remember: true,
	}
	for _, fn := range options {
		fn(ac)
	}
	c.Accounts[index] = ac
	return viper.WriteConfig()
}

// 默认配置
const (
	retryTime  = 3
	retryDelay = 15
	commitTime = "00 7,12 * * *"
)

// 加载配置文件
func LoadConfig() (err error) {
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(".")
	viper.SetDefault("Retry", retryTime)
	viper.SetDefault("RetryDelay", retryDelay)
	viper.SetDefault("CommitTime", commitTime)
	if err = viper.ReadInConfig(); err != nil {
		return
	}
	if err = viper.Unmarshal(Cfg); err != nil {
		return
	}
	// 配置监控
	viper.WatchConfig()
	viper.OnConfigChange(func(e fsnotify.Event) {
		log.Logger.Info("配置监控", zap.String("发生改变", e.String()))
		if err := viper.Unmarshal(Cfg); err != nil {
			log.Logger.Error("配置监控", zap.Error(err), zap.String("事件", e.String()))
		}
	})
	return
}
